using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using MercuryParticleEngine;
using MercuryParticleEngine.Emitters;
using MercuryParticleEngine.Modifiers;

namespace BumbleGame
{
    class Level1
    {
        //Global variables for this class
        #region Class Globals        
        private AnimatedTexture Coin, SidePig, SidePigWings, ConfidenceFlower, ConfidenceFlowerFill, ConfidenceFlowerCup, ConfidenceFlowerPetals, PicketFence;
        private Flower BlueFlower01, RedFlower01, YellowFlower01, BlueMale01, RedMale01, YellowMale01; //worm1;
        private ScrollingBackground myBackground;
        private List<Flower> MaleFlowerList, FemaleFlowerList;
        public List<Bug> BugList, BossBugs1;
        //geoff flies
        public List<Bug> BossFlies;
        private List<Vector2> FlyStartingPosition;
        //end geoff flies
        private List<AnimatedTexture> BGElementList;
        private int pollenIndex, levelRowIndex, levelColumnIndex, bossfliesColumnIndex, bossfliesRowIndex, leftFootColor, rightFootColor, nOldStreakCount, currentLevel;
        private float time, bossfliesTime;
        public List<PollenBall> PollenList;
        private PollenBall pollenBall;
        private float fStreakMultiplier, fCurrentBoost, fOldMeterPosition, fBaseBoost, fStreakTimer, fStreakTimerLimit, fBaseDrain, fDrain1, fDrain2, fDrain3;
        public float fTotalBoost, fTotalConfidenceMeter;
        public int nStreakCount, nConfidenceMode, nLastPollenCloudColor;
        public bool justPollenated, isBossDefeated, endsequence, isFiveStreak;
        private bool finalMoments, freezeBackround;
        private bool firstLoad = true;
        #endregion Class Globals

        //boss variables
        public AnimatedTexture KidFace, KidFaceDetected, KidFaceSniffling, KidFaceSneezing, KidLighter, KidCan, FireCloud, KidSniffles;
        private List<AnimatedTexture> SprayClouds;
        private bool initializingBoss, isMovingLighter, isLighterAtRest, isCanAtRest, isFireMoving, sneezingPhase, isBreathingIn, isKidInvulnerable, isBossDying;
        public bool isFireSpraying;
        private float fLighterPatrolTimer, fLighterDirectionTimer, fLighterTopSpeed, fLighterReturnAngle,
            fSquirtTimer, fFireSprayTimer, fBreathingTimer, fBreathingDistance, fireBoxHeight, fFlyAngle, fBossFlyTopSpeed;
        private Vector2 KidFaceAtRest, KidLighterAtRest, KidCanAtRest, LighterReturnPath, LighterReturnPathToCan, FlyPath;
        private int nLighterDirection, nTotalSquirts, nSquirtIndex, nSquirtInterval, nPhaseCount, nBossLife;
        private HitBox2D fireBox;
        
        
        
        //load resources for level 1
        //import global bumblepig
        //might be able to just use ref to reference the global pig data
        //apparently classes are always passed as references so it doesn't need to be forced
        public void Load(Viewport viewport, ContentManager content,GraphicsDeviceManager graphics, Bumblepig loadPig, Emitter emitterLeft, Emitter emitterRight, Emitter emitterLeftConstant, Emitter emitterRightConstant, ParticleSystem pSystem, ref tagScreenFade ScreenFade, string backgroundTexture, int level) //, ref List<PollenBall> pollenList)  //Flower PollenBall1, Flower PollenBall2)
        {
            

            // Positions for Flowers, Pollen, Bugs
            #region Level Layout
            
            pollenIndex = 0;
            
           
            #endregion Level Layout

            // Level Class Initialization
            #region Level Object Init
                        
            SidePig = new AnimatedTexture();
            SidePigWings = new AnimatedTexture();            
            PicketFence = new AnimatedTexture();
            //new confidence meter
            ConfidenceFlower = new AnimatedTexture();
            ConfidenceFlowerFill = new AnimatedTexture();
            ConfidenceFlowerCup = new AnimatedTexture();
            ConfidenceFlowerPetals = new AnimatedTexture();
            //flowers, bugs, and background images
            MaleFlowerList = new List<Flower>();
            FemaleFlowerList = new List<Flower>();
            PollenList = new List<PollenBall>();
            BugList = new List<Bug>();
            BossBugs1 = new List<Bug>();
            BGElementList = new List<AnimatedTexture>();
            
            

            Coin = new AnimatedTexture();
   
            myBackground = new ScrollingBackground();
               
            #endregion Level Object Init

            // Emitter Layouts
            #region Emitter Layout
            // emitter init values for pollen balls, maybe move to level class
            //emitter = new Emitter(1000);
            if (!firstLoad)
            {
                //still skips first pollen spawn point when loading level again
                //only happens if that specific side was used                               
                emitterLeft= new Emitter(1000);                
                emitterRight= new Emitter(1000);
                emitterLeftConstant = new Emitter(500);
                emitterRightConstant = new Emitter(500);
                //PollenBall1.ResetPollen();
                //PollenBall2.ResetPollen();


            }
            emitterLeft.DischargeQuantity = 0;
            emitterLeft.ParticleSpeed = 20f;
            emitterLeft.ParticleSpeedRange = 20f;
            emitterLeft.ParticleLifespan = 1500;
            emitterLeft.ImageStrip = "Default";
            emitterLeft.Frame = 4;            
            //Modifier randomScale1 = new RandomScaleModifier(.1f, pollenScale1);
            //emitter.ApplyModifier(randomScale1);
            emitterLeft.ApplyModifier(new GravityModifier(MathHelper.PiOver2, 170f));
            pSystem.AddEmitter(emitterLeft);

            //right foot pollen emitter
            //emitter2 = new Emitter(1000);
            emitterRight.DischargeQuantity = 0;
            emitterRight.ParticleSpeed = 20f;
            emitterRight.ParticleSpeedRange = 20f;
            emitterRight.ParticleLifespan = 1500;
            emitterRight.ImageStrip = "Default";
            emitterRight.Frame = 4;
            //Modifier randomScale2 = new RandomScaleModifier(.1f, pollenScale2);
            //emitter2.ApplyModifier(randomScale2);
            emitterRight.ApplyModifier(new GravityModifier(MathHelper.PiOver2, 170f));
            pSystem.AddEmitter(emitterRight);

            emitterLeftConstant.DischargeQuantity = 0;
            emitterLeftConstant.ParticleSpeed = 5f;
            emitterLeftConstant.ParticleSpeedRange = 10f;
            emitterLeftConstant.ParticleLifespan = 1000;
            emitterLeftConstant.ImageStrip = "Default";
            emitterLeftConstant.Frame = 4;
            //Modifier randomScale1 = new RandomScaleModifier(.1f, pollenScale1);
            //emitter.ApplyModifier(randomScale1);
            emitterLeftConstant.ApplyModifier(new GravityModifier(MathHelper.PiOver2, 170f));
            pSystem.AddEmitter(emitterLeftConstant);

            emitterRightConstant.DischargeQuantity = 0;
            emitterRightConstant.ParticleSpeed = 5f;
            emitterRightConstant.ParticleSpeedRange = 10f;
            emitterRightConstant.ParticleLifespan = 1000;
            emitterRightConstant.ImageStrip = "Default";
            emitterRightConstant.Frame = 4;
            //Modifier randomScale1 = new RandomScaleModifier(.1f, pollenScale1);
            //emitter.ApplyModifier(randomScale1);
            emitterRightConstant.ApplyModifier(new GravityModifier(MathHelper.PiOver2, 170f));
            pSystem.AddEmitter(emitterRightConstant);
            
            #endregion Emitter Layout

            //load bumblepigs textures and set his positions...
            loadPig.LoadPig(viewport, content, graphics);

            // Load Textures
            #region Textures
            // Load animated textures and put bumblepig in the middle of the screen
            SidePig.Load(graphics.GraphicsDevice, content, "Images/bp_status_yellow", 1, 2, 60, 0, 1, false);
            SidePigWings.Load(graphics.GraphicsDevice, content, "Images/bp_status_wings_strip", 8, 1, 48, 0, 7, false);
            //new confidence meter images
            ConfidenceFlower.Load(graphics.GraphicsDevice, content, "Images/flowerpower_meter_5", 1, 4, 1, 0, 0, false);
            ConfidenceFlowerFill.Load(graphics.GraphicsDevice, content, "Images/flowermeter_mercury", 1, 1, 1, 0, 0, false);
            ConfidenceFlowerFill.recWidth = 0.0f;
            ConfidenceFlowerCup.Load(graphics.GraphicsDevice, content, "Images/flowermeter_flowercup", 1, 1, 1, 0, 0, false);
            ConfidenceFlowerPetals.Load(graphics.GraphicsDevice, content, "Images/flowermeter_petals", 5, 1, 60, 0, 0, false);

            PicketFence.Load(graphics.GraphicsDevice, content, "Images/BGElements/end_fence", 1, 1, 1, 0, 0, false);

            Texture2D background = content.Load<Texture2D>(backgroundTexture);

            #endregion Textures

            // Initial Object Positions
            #region Initial Positions            
            emitterLeft.Position = new Vector2(loadPig.BumbleBody.SpritePosition.X - 40, loadPig.BumbleBody.SpritePosition.Y + 40);
            emitterRight.Position = new Vector2(loadPig.BumbleBody.SpritePosition.X + 40, loadPig.BumbleBody.SpritePosition.Y + 40);

            SidePig.SpritePosition = new Vector2(100f, 675f);
            SidePigWings.SpritePosition = new Vector2(85f, 640f);
            SidePigWings.SpriteScale = 1.25f;
            //new confidence meter positions
            ConfidenceFlower.SpritePosition = new Vector2(480, 675);
            ConfidenceFlowerFill.SpritePosition = new Vector2(520, 675);
            ConfidenceFlowerCup.SpritePosition = new Vector2(960, 690);
            ConfidenceFlowerPetals.SpritePosition = new Vector2(930, 690);

            PicketFence.SpritePosition = new Vector2((viewport.Width / 2), (0 - PicketFence.aTexture.Height));

            #endregion Initial Positions
            //Misc Values for Objects       
                        
            myBackground.Load(graphics.GraphicsDevice, background);

            #region variable_instantiation

            currentLevel = level;
            levelRowIndex = 0;
            levelColumnIndex = 0;
            leftFootColor = 0;
            rightFootColor = 0;
            time = 0;

            //Confidence meter variables
            //these are the constants that can be manipulated to tune the scoring system
            fStreakMultiplier = 1.5f;
            fBaseBoost = (float)(ConfidenceFlowerFill.aTexture.Width * 0.01);
            fStreakTimerLimit = 2.0f;
            fBaseDrain = (float)(ConfidenceFlowerFill.aTexture.Width * 0.00005);
            fDrain1 = fBaseDrain * 1.5f;
            fDrain2 = fBaseDrain * 2.25f;
            fDrain3 = fBaseDrain * 3.375f;

            //These should all stay the same
            fTotalConfidenceMeter = 0.0f;            
            fCurrentBoost = fBaseBoost;
            fTotalBoost = fCurrentBoost;
            fStreakTimer = 0.0f;            
            nStreakCount = 0;
            nConfidenceMode = 0;
            nOldStreakCount = 0;
            nLastPollenCloudColor = 0;
            justPollenated = false;
            isFiveStreak = false;

            //ending variables
            endsequence = false;
            isBossDefeated = false;
            finalMoments = false;
            freezeBackround = false;


            //boss variable initialization
            //testTimer = 0.0f;
            bossfliesColumnIndex = 0;
            bossfliesRowIndex = 0;
            bossfliesTime = 0;
            isMovingLighter = false;
            isLighterAtRest = false;
            isCanAtRest = false;
            isFireMoving = false;
            isFireSpraying = false;
            sneezingPhase = false;
            isBreathingIn = false;
            isBossDying = false;
            fBreathingDistance = 5.0f;
            fBreathingTimer = 0.0f;
            fLighterPatrolTimer = 0.0f;
            fLighterDirectionTimer = 0.0f;
            fLighterTopSpeed = 5.0f;
            fBossFlyTopSpeed = 5.0f;
            fSquirtTimer = 0.0f;
            fFireSprayTimer = 0.0f;
            nPhaseCount = 0;
            fireBoxHeight = 0.0f;
            nBossLife = 3;
            #endregion variable_instantiation

            //boss crap
            //first boss init
            if (currentLevel == 2)
            {
                KidCan = new AnimatedTexture();
                KidFace = new AnimatedTexture();
                KidLighter = new AnimatedTexture();
                FireCloud = new AnimatedTexture();
                KidSniffles = new AnimatedTexture();
                KidFaceDetected = new AnimatedTexture();
                KidFaceSniffling = new AnimatedTexture();
                KidFaceSneezing = new AnimatedTexture();
                KidCan.Load(graphics.GraphicsDevice, content, "Images/boss_spraycan2", 1, 1, 1, 0, 0, false);
                KidFace.Load(graphics.GraphicsDevice, content, "Images/boss_face2", 1, 1, 1, 0, 0, false);
                KidFaceDetected.Load(graphics.GraphicsDevice, content, "Images/boss_face_detected", 1, 1, 1, 0, 0, false);
                KidFaceSniffling.Load(graphics.GraphicsDevice, content, "Images/boss_face_sniffle", 1, 1, 1, 0, 0, false);
                KidFaceSneezing.Load(graphics.GraphicsDevice, content, "Images/boss_face_sneeze", 1, 1, 1, 0, 0, false);
                KidLighter.Load(graphics.GraphicsDevice, content, "Images/boss_lighter2", 1, 1, 1, 0, 0, false);
                FireCloud.Load(graphics.GraphicsDevice, content, "Images/boss_fire_oneframe", 1, 1, 1, 0, 0, false);
                KidSniffles.Load(graphics.GraphicsDevice, content, "Images/sniffle", 4, 1, 12, 1, 4, false);
                KidCan.SpritePosition = new Vector2(900, (0 - (KidCan.aTexture.Height / 2)));
                KidFace.SpritePosition = new Vector2(512, (0 - (KidFace.aTexture.Height / 2)));
                KidLighter.SpritePosition = new Vector2(100, (0 - (KidLighter.aTexture.Height / 2)));
                FireCloud.SpritePosition = new Vector2(KidCan.SpritePosition.X, KidCan.SpritePosition.Y);               
                KidCan.SpriteRotation = 0.0f;
                KidLighter.SpriteRotation = -0.0f;

                KidCanAtRest = new Vector2(900, 50);
                KidFaceAtRest = new Vector2(512, 50);
                KidLighterAtRest = new Vector2(100, 50);
                LighterReturnPathToCan = new Vector2(KidCanAtRest.X, (KidCanAtRest.Y + 100.0f));
                KidSniffles.SpritePosition = new Vector2(KidFaceAtRest.X, (KidFaceAtRest.Y + 250.0f));                

                //initialize spray clouds
                SprayClouds = new List<AnimatedTexture>();
                for (int i = 0; i < 16; i++)
                {
                    SprayClouds.Add(new AnimatedTexture());
                    //SprayClouds[i] = new AnimatedTexture();
                    SprayClouds[i].Load(graphics.GraphicsDevice, content, "Images/boss_spraycloud", 1, 1, 1, 0, 0, false);
                    SprayClouds[i].SpritePosition = KidCanAtRest;
                }

                //geoff flies
                //initialize boss flies
                FlyStartingPosition = new List<Vector2>();


                BossFlies = new List<Bug>();
                for (int i = 0; i < 3; i++)
                {
                    BossFlies.Add(new Bug(viewport.Height, "fly", 0, graphics, content));
                    BossFlies[i].Load(graphics.GraphicsDevice, content, "Images/Enemies/bug_fly_3of8", 8, 1, 12, 0, 2, true);
                    //spawns flys from the bottom of the screen
                    FlyStartingPosition.Add(new Vector2((float)viewport.Width * ((float)i / 2), viewport.Height));
                    BossFlies[i].SpritePosition = FlyStartingPosition[i];
                }
                //end geoff flies

                initializingBoss = true;
            }

            if (firstLoad == true) firstLoad = false;
        }

        //update logic for level 1
        public void Update(float elapsed, Bumblepig bumblepig, Emitter uEmitterLeft, Emitter uEmitterRight, Emitter uEmitterLeftConstant, Emitter uEmitterRightConstant, SoundBank sfxBank, List<List<char>> levelMap, List<List<char>> bossfliesMap, GraphicsDeviceManager graphics, ContentManager content, Viewport viewport, ref int gamestate, ref FlowerTotals totalFlowers, ref tagScreenFade ScreenFade, LevelTextures levTex, ref float musicVolume)
        {            
            if (endsequence)
            {                
                //scripting crap
                if (!isBossDefeated) //if this level has a boss fight go here until he's done
                {
                    if (currentLevel == 2)
                    {                        
                        fTotalBoost = 200;
                        updateBossKid(bumblepig, elapsed, sfxBank);
                        
                        //update the layout of bugs for this fight
                        updateBossfliesLayout(bossfliesMap, elapsed, graphics, content, viewport);
                        for (int i = 0; i < BossBugs1.Count; i++)
                        {
                            BossBugs1[i].UpdateBug(elapsed, bumblepig, FemaleFlowerList);
                            BossBugs1[i].CheckDamage(bumblepig, sfxBank, BossBugs1);
                            if (!BossBugs1[i].isVisible) BossBugs1.Remove(BossBugs1[i]);
                        }
                    }

                    if (currentLevel != 2) isBossDefeated = true;
                
                } 
                else
                {
                    updateEndSequence(bumblepig, viewport, elapsed);
                } 
                //after it finishes
                //if black texture is fully opaque or endsequence is set back to false, then make gamestate = 2                
                if (!endsequence)
                { ScreenFade.Begin(Screen.Results, FadeType.FadeOut, 0.5f, musicVolume); }
            }
           
            //update bumblepig, wings and shadow animations            
            bumblepig.UpdateBumblepig(elapsed, nConfidenceMode, SidePig);
            
            //update status indicator
            SidePig.UpdateFrame(elapsed);
            SidePigWings.UpdateFrame(elapsed);
            
            
            
            foreach (PollenBall pollenBall in PollenList)
            {
                pollenBall.Update(elapsed * 100, elapsed, uEmitterLeft, uEmitterRight, uEmitterLeftConstant, uEmitterRightConstant, bumblepig, PollenList);
                if (pollenBall.pollenState == 1)
                {
                    leftFootColor = pollenBall.color;
                }
                if (pollenBall.pollenState == 2)
                {
                    rightFootColor = pollenBall.color;
                }
            }    
            //start in-game only section
            if (!freezeBackround)
            { 
                //update the level map
                updateLayout(levelMap, elapsed, graphics, content, viewport, levTex);
                for (int i = 0; i < MaleFlowerList.Count; i++)//foreach (Flower maleFlower in MaleFlowerList)
                {
                    MaleFlowerList[i].UpdateFlower(elapsed * 100, elapsed);
                    if (!MaleFlowerList[i].pollenGone && !MaleFlowerList[i].occupied && MaleFlowerList[i].isVisible)
                    {
                        PollenList[pollenIndex].SpritePosition = MaleFlowerList[i].flower.SpritePosition;
                        PollenList[pollenIndex].color = MaleFlowerList[i].color;
                        PollenList[pollenIndex].isInPlay = true;
                        PollenList[pollenIndex].Pause();
                        pollenIndex++;
                        MaleFlowerList[i].occupied = true;
                    }
                    if (!MaleFlowerList[i].isVisible)
                    { MaleFlowerList.Remove(MaleFlowerList[i]); }
                }
                for (int i = 0; i < FemaleFlowerList.Count; i++)//foreach (Flower femaleFlower in FemaleFlowerList)
                {
                    FemaleFlowerList[i].UpdateFlower(elapsed * 100, elapsed, uEmitterLeft.GetParticlePositions(), uEmitterRight.GetParticlePositions(), sfxBank, bumblepig, rightFootColor, leftFootColor, ref nStreakCount, ref justPollenated, nConfidenceMode, ref nLastPollenCloudColor, ref totalFlowers);
                    //maybe put this back in later
                    //maybe not needed at all
                    //dump list at end of level instead
                    //if (!FemaleFlowerList[i].isVisible)
                    //{ FemaleFlowerList.Remove(FemaleFlowerList[i]); }
                }

                for (int i = 0; i < BugList.Count; i++)
                {
                    BugList[i].UpdateBug(elapsed, bumblepig, FemaleFlowerList);
                    BugList[i].CheckDamage(bumblepig, sfxBank, BugList);
                    BugList[i].CheckPowerUp(ref fTotalConfidenceMeter, bumblepig.BumbleBody.HitBox2);
                    if (BugList[i].isFireFly)
                    {
                        if (BugList[i].dead && !BugList[i].isPickUpActive) BugList.Remove(BugList[i]);
                    }
                    else
                    {
                        if (!BugList[i].isVisible) BugList.Remove(BugList[i]);
                    }
                    
                }

                //updating confidence meter here...
                fStreakTimer += elapsed;
                updateConfidence(bumblepig);

                //Updating new confidence meter images...
                ConfidenceFlowerFill.UpdateFrame(elapsed);
                ConfidenceFlowerCup.UpdateFrame(elapsed);
                //Update the flower stem so that it displays the power ups associated with the correct Confidence Mode here:
                ConfidenceFlower.firstFrame = nConfidenceMode;
                ConfidenceFlower.lastFrame = nConfidenceMode;
                ConfidenceFlower.UpdateFrame(elapsed);
                //Update flower petals that track the streaks here using nStreakCount and nLastPollenCloudColor
                //pollen cloud color: 0 = blue, 1 = red, 2 = yellow, 3 = purple, 4 = green, 5 = orange
                ConfidenceFlowerPetals.firstFrame = nStreakCount - 1;
                ConfidenceFlowerPetals.lastFrame = nStreakCount - 1;
                if (isFiveStreak && nStreakCount == 0)
                {
                    ConfidenceFlowerPetals.firstFrame = 4;
                    ConfidenceFlowerPetals.lastFrame = 4;
                }
                if (nStreakCount > 0) isFiveStreak = false;


                switch (nLastPollenCloudColor)
                {
                    case 0:
                        ConfidenceFlowerPetals.tint = Color.Blue;
                        break;
                    case 1:
                        ConfidenceFlowerPetals.tint = Color.Red;
                        break;
                    case 2:
                        ConfidenceFlowerPetals.tint = Color.Yellow;
                        break;
                    case 3:
                        ConfidenceFlowerPetals.tint = Color.Purple;
                        break;
                    case 4:
                        ConfidenceFlowerPetals.tint = Color.Green;
                        break;
                    case 5:
                        ConfidenceFlowerPetals.tint = Color.Orange;
                        break;
                }
                ConfidenceFlowerPetals.UpdateFrame(elapsed);


                //worm1.UpdateFlower(elapsed * 130, elapsed, totalTime); //make him not a flower

                //make shift pollen to foot connection
                /*foreach (PollenBall pollenBall in PollenList)
                {
                    pollenBall.Update(elapsed * 100, elapsed, uEmitter, uEmitter2, bumblepig, PollenList);
                    if (pollenBall.pollenState == 1)
                    {
                        leftFootColor = pollenBall.color;
                    }
                    if (pollenBall.pollenState == 2)
                    {
                        rightFootColor = pollenBall.color;
                    }
                } */           
                //end in-game only section

                //move the background texture at 100 pixels/sec
                myBackground.Update(elapsed * 100);
                for (int i = 0; i < BGElementList.Count; i++)
                {
                    BGElementList[i].UpdateFrame(elapsed);
                    BGElementList[i].SpritePosition.Y += elapsed * 100;
                    if (BGElementList[i].SpritePosition.Y > (viewport.Height + BGElementList[i].aTexture.Height)) BGElementList.Remove(BGElementList[i]);
                }
            }

        }

        //draw graphics for level 1
        public void Draw(SpriteBatch LevelOneBatch, Bumblepig drawPig) //, List<PollenBall> pollenList)
        {
            //LevelOneBatch.Begin();
            myBackground.Draw(LevelOneBatch);

            //if endsequence then draw fence
            if (endsequence)
            { PicketFence.DrawFrame(LevelOneBatch); }


            if (!drawPig.dead)
            {
                drawPig.DrawPigShadow(LevelOneBatch);
            }
            //worm1.Draw(LevelOneBatch);
            
            //draw boss crap
            if (currentLevel == 2 && endsequence)
            {
                //geoff flies
                for (int i = 0; i < 3; i++)
                {
                    if (BossFlies[i].isVisible) BossFlies[i].Draw(LevelOneBatch);

                }
                //end geoff flies

                //draw his normal face
                if (!isFireMoving && !isBreathingIn && !isKidInvulnerable) KidFace.DrawFrame(LevelOneBatch);

                //draw angry face if he has seen you
                if (isFireMoving) KidFaceDetected.DrawFrame(LevelOneBatch);

                //sneezing face after he gets hit
                if (isKidInvulnerable) KidFaceSneezing.DrawFrame(LevelOneBatch);
                
                //breathing face and lines while he is breathing in
                if (isBreathingIn && !isKidInvulnerable) 
                {
                    KidSniffles.DrawFrame(LevelOneBatch);
                    KidFaceSniffling.DrawFrame(LevelOneBatch);
                }
                KidCan.DrawFrame(LevelOneBatch);
                KidLighter.DrawFrame(LevelOneBatch);
                if (nSquirtIndex > 0)
                {
                    for (int i = 0; i < (4 * nSquirtIndex); i++)
                    {
                        SprayClouds[i].DrawFrame(LevelOneBatch);
                    }
                }
                if (isFireSpraying) FireCloud.DrawFrame(LevelOneBatch);
            }
            
            if (!drawPig.onTopLayer && !drawPig.dead)
            {
                drawPig.DrawPig(LevelOneBatch, nConfidenceMode);
                foreach (PollenBall pollenBall in PollenList)
                {
                    if (pollenBall.pollenState == 1 || pollenBall.pollenState == 2)
                    {
                        pollenBall.DrawFrame(LevelOneBatch);
                    }
                }                
            }
            foreach (Flower maleFlower in MaleFlowerList)
            { maleFlower.DrawStem(LevelOneBatch); }
            foreach (Flower femaleFlower in FemaleFlowerList)
            { femaleFlower.DrawStem(LevelOneBatch); }
            foreach (Flower maleFlower in MaleFlowerList)
            { maleFlower.DrawFlower(LevelOneBatch); }
            foreach (Flower femaleFlower in FemaleFlowerList)
            { femaleFlower.DrawFlower(LevelOneBatch); }

            foreach (Bug bugX in BugList)
            { bugX.Draw(LevelOneBatch); }

            //draw the fireflies for the boss fight
            foreach (Bug bugX in BossBugs1)
            { bugX.Draw(LevelOneBatch); }
            

            if (drawPig.onTopLayer && !drawPig.dead)
            {
                drawPig.DrawPig(LevelOneBatch, nConfidenceMode);                    
            }

            foreach (PollenBall pollenBall in PollenList)
            {
                if (pollenBall.isInPlay)
                {
                    pollenBall.DrawFrame(LevelOneBatch);
                }
            }

            //LevelOneBatch.End();

        }

        public void DrawHUD(SpriteBatch LevelOneHUDBatch)
        {
            //New confidence meter draw calls... Flower and Petals need updates to advance the frames            
            ConfidenceFlowerFill.DrawFrame(LevelOneHUDBatch, ConfidenceFlowerFill.recWidth, ConfidenceFlowerFill.recHeight);
            ConfidenceFlower.DrawFrame(LevelOneHUDBatch);
            if (nStreakCount != 0 || isFiveStreak) ConfidenceFlowerPetals.DrawFrame(LevelOneHUDBatch);
            ConfidenceFlowerCup.DrawFrame(LevelOneHUDBatch);

            //draw status pig
            SidePig.DrawFrame(LevelOneHUDBatch);
            SidePigWings.DrawFrame(LevelOneHUDBatch);
        }


        //extra functions to call in the update loop to make things a little more readable

        //function to read through the level map and create and place game objects
        public void updateLayout(List<List<char>> levelmap, float elapsed, GraphicsDeviceManager graphics, ContentManager content, Viewport viewport, LevelTextures levTex)
        {           
            time += elapsed;
            if (levelRowIndex < levelmap.Count)
            {
                if (time > 0.5f)
                {
                    for (levelColumnIndex = 0; levelColumnIndex < levelmap[levelRowIndex].Count; levelColumnIndex++)
                    {
                        float xPosition = (levelColumnIndex + 1) * 50;
                        char ch = levelmap[levelRowIndex][levelColumnIndex];
                        Bug bugX;
                        AnimatedTexture BGElement;

                        switch (ch)
                        {
                        //Flowers:
                            case 'c': //blue male flower creation with pollen balls
                                BlueMale01 = new Flower(viewport.Height, 0, false);
                                BlueMale01.Load(graphics, content, levTex.blueFlowerMale);
                                BlueMale01.stem.SpritePosition.X = xPosition;                                
                                MaleFlowerList.Add(BlueMale01);
                                pollenBall = new PollenBall();
                                pollenBall.Load(graphics.GraphicsDevice, content, "Images/pollen_dummy", 1, 1, 1, 0, 0, false);
                                PollenList.Add(pollenBall);
                                break;
                            case 'b': //blue female flower creation with pollen balls
                                BlueFlower01 = new Flower(viewport.Height, 0, true);
                                BlueFlower01.Load(graphics, content, levTex.blueFlowerFemale);
                                BlueFlower01.stem.SpritePosition.X = xPosition;
                                FemaleFlowerList.Add(BlueFlower01);
                                break;
                            case 's': //red female flower creation with pollen balls
                                RedMale01 = new Flower(viewport.Height, 1, false);
                                RedMale01.Load(graphics, content, levTex.redFlowerMale);
                                RedMale01.stem.SpritePosition.X = xPosition;
                                MaleFlowerList.Add(RedMale01);
                                pollenBall = new PollenBall();
                                pollenBall.Load(graphics.GraphicsDevice, content, "Images/pollen_dummy", 1, 1, 1, 0, 0, false);
                                PollenList.Add(pollenBall);
                                break;
                            case 'r': //red female flower creation with pollen balls
                                RedFlower01 = new Flower(viewport.Height, 1, true);
                                RedFlower01.Load(graphics, content, levTex.redFlowerFemale);
                                RedFlower01.stem.SpritePosition.X = xPosition;
                                FemaleFlowerList.Add(RedFlower01);
                                break;
                            case 'z': //yellow female flower creation with pollen balls
                                YellowMale01 = new Flower(viewport.Height, 2, false);
                                YellowMale01.Load(graphics, content, levTex.yellowFlowerMale);
                                YellowMale01.stem.SpritePosition.X = xPosition;
                                MaleFlowerList.Add(YellowMale01);
                                pollenBall = new PollenBall();
                                pollenBall.Load(graphics.GraphicsDevice, content, "Images/pollen_dummy", 1, 1, 1, 0, 0, false);
                                PollenList.Add(pollenBall);
                                break;
                            case 'y': //yellow female flower creation with pollen balls
                                YellowFlower01 = new Flower(viewport.Height, 2, true);
                                YellowFlower01.Load(graphics, content, levTex.yellowFlowerFemale);
                                YellowFlower01.stem.SpritePosition.X = xPosition;
                                FemaleFlowerList.Add(YellowFlower01);
                                break;
                        //Bugs:
                            case 'f': //fly enemy
                                bugX = new Bug(viewport.Height, "fly", elapsed * 200, graphics, content);
                                bugX.Load(graphics.GraphicsDevice, content, "Images/Enemies/bug_fly_3of8", 8, 1, 12, 0, 2, true);
                                bugX.SpritePosition = new Vector2((int)xPosition, 0 - (bugX.aTexture.Height / 2));
                                BugList.Add(bugX);
                                break;
                            case 'd': //dragonfly enemy
                                bugX = new Bug(viewport.Height, "dragonfly", elapsed * 275, graphics, content);
                                bugX.Load(graphics.GraphicsDevice, content, "Images/Enemies/bug_dragonfly_3of4", 4, 1, 12, 0, 2, true);
                                bugX.SpritePosition = new Vector2((int)xPosition, 0 - (bugX.aTexture.Height / 2));
                                BugList.Add(bugX);
                                break;
                            case 'g': //grasshopper enemy
                                bugX = new Bug(viewport.Height, "grasshopper", elapsed * 100, graphics, content);
                                bugX.Load(graphics.GraphicsDevice, content, "Images/Enemies/bug_grasshopper", 1, 1, 1, 0, 0, false);
                                bugX.SpritePosition = new Vector2((int)xPosition, 0 - (bugX.aTexture.Height / 2));
                                BugList.Add(bugX);
                                break;
                            case 'e': //butterfly enemy
                                bugX = new Bug(viewport.Height, "butterfly", elapsed * 100, graphics, content);
                                bugX.Load(graphics.GraphicsDevice, content, "Images/Enemies/bug_moth", 1, 1, 1, 0, 0, false);
                                bugX.SpritePosition = new Vector2((int)xPosition, 0 - (bugX.aTexture.Height / 2));
                                BugList.Add(bugX);
                                break;
                            case 'h': //pacer bug enemy
                                bugX = new Bug(viewport.Height, "pacer", elapsed * 100, graphics, content);
                                bugX.Load(graphics.GraphicsDevice, content, "Images/Enemies/bug_ladybug", 1, 1, 1, 0, 0, false);
                                bugX.SpritePosition = new Vector2((int)xPosition, 0 - (bugX.aTexture.Height / 2));
                                BugList.Add(bugX);
                                break;
                            case 'i': //frog enemy
                                bugX = new Bug(viewport.Height, "frog", elapsed * 100, graphics, content);
                                if (xPosition < viewport.Width / 2) bugX.Load(graphics.GraphicsDevice, content, "Images/Enemies/frog", 1, 1, 1, 0, 0, false);
                                else
                                {
                                    bugX.Load(graphics.GraphicsDevice, content, "Images/Enemies/frog", 1, 1, 1, 0, 0, false);
                                    bugX.spriteFX = SpriteEffects.FlipHorizontally;
                                }
                                bugX.SpritePosition = new Vector2((int)xPosition, 0 - (bugX.aTexture.Height / 2));
                                if (xPosition > viewport.Width / 2) bugX.FlipTongue();
                                BugList.Add(bugX);
                                break;
                            case 'j': //firefly enemy
                                bugX = new Bug(viewport.Height, "firefly", elapsed * 200, graphics, content);
                                bugX.Load(graphics.GraphicsDevice, content, "Images/Enemies/bug_firefly_bodystrip", 4, 1, 8, 0, 0, true);
                                bugX.SpritePosition = new Vector2((int)xPosition, 0 - (bugX.aTexture.Height / 2));
                                BugList.Add(bugX);
                                break;
                        //Background Elements... please let them stay static...
                            /*case '0':
                                BGElement = new AnimatedTexture();
                                BGElement.Load(graphics.GraphicsDevice, content, levTex.BGElement0, levTex.BGElement0framesWide, levTex.BGElement0framesTall,
                                               levTex.BGElement0framesPerSec, 0, levTex.BGElement0lastFrame, levTex.BGElement0sym);
                                BGElement.SpritePosition = new Vector2((int)xPosition, 0 - (BGElement.aTexture.Height / 2));
                                BGElementList.Add(BGElement);
                                break;
                            case '1':
                                BGElement = new AnimatedTexture();
                                BGElement.Load(graphics.GraphicsDevice, content, levTex.BGElement1, levTex.BGElement1framesWide, levTex.BGElement1framesTall,
                                               levTex.BGElement1framesPerSec, 0, levTex.BGElement1lastFrame, levTex.BGElement1sym);
                                BGElement.SpritePosition = new Vector2((int)xPosition, 0 - (BGElement.aTexture.Height / 2));
                                BGElementList.Add(BGElement);
                                break;
                            case '2':
                                BGElement = new AnimatedTexture();
                                BGElement.Load(graphics.GraphicsDevice, content, levTex.BGElement2, levTex.BGElement2framesWide, levTex.BGElement2framesTall,
                                               levTex.BGElement2framesPerSec, 0, levTex.BGElement2lastFrame, levTex.BGElement2sym);
                                BGElement.SpritePosition = new Vector2((int)xPosition, 0 - (BGElement.aTexture.Height / 2));
                                BGElementList.Add(BGElement);
                                break;
                            case '3':
                                BGElement = new AnimatedTexture();
                                BGElement.Load(graphics.GraphicsDevice, content, levTex.BGElement3, levTex.BGElement3framesWide, levTex.BGElement3framesTall,
                                               levTex.BGElement3framesPerSec, 0, levTex.BGElement3lastFrame, levTex.BGElement3sym);
                                BGElement.SpritePosition = new Vector2((int)xPosition, 0 - (BGElement.aTexture.Height / 2));
                                BGElementList.Add(BGElement);
                                break;
                            case '4':
                                BGElement = new AnimatedTexture();
                                BGElement.Load(graphics.GraphicsDevice, content, levTex.BGElement4, levTex.BGElement4framesWide, levTex.BGElement4framesTall,
                                               levTex.BGElement4framesPerSec, 0, levTex.BGElement4lastFrame, levTex.BGElement4sym);
                                BGElement.SpritePosition = new Vector2((int)xPosition, 0 - (BGElement.aTexture.Height / 2));
                                BGElementList.Add(BGElement);
                                break;
                            case '5':
                                BGElement = new AnimatedTexture();
                                BGElement.Load(graphics.GraphicsDevice, content, levTex.BGElement5, levTex.BGElement5framesWide, levTex.BGElement5framesTall,
                                               levTex.BGElement5framesPerSec, 0, levTex.BGElement5lastFrame, levTex.BGElement5sym);
                                BGElement.SpritePosition = new Vector2((int)xPosition, 0 - (BGElement.aTexture.Height / 2));
                                BGElementList.Add(BGElement);
                                break;
                            case '6':
                                BGElement = new AnimatedTexture();
                                BGElement.Load(graphics.GraphicsDevice, content, levTex.BGElement6, levTex.BGElement6framesWide, levTex.BGElement6framesTall,
                                               levTex.BGElement6framesPerSec, 0, levTex.BGElement6lastFrame, levTex.BGElement6sym);
                                BGElement.SpritePosition = new Vector2((int)xPosition, 0 - (BGElement.aTexture.Height / 2));
                                BGElementList.Add(BGElement);
                                break;
                            case '7':
                                BGElement = new AnimatedTexture();
                                BGElement.Load(graphics.GraphicsDevice, content, levTex.BGElement7, levTex.BGElement7framesWide, levTex.BGElement7framesTall,
                                               levTex.BGElement7framesPerSec, 0, levTex.BGElement7lastFrame, levTex.BGElement7sym);
                                BGElement.SpritePosition = new Vector2((int)xPosition, 0 - (BGElement.aTexture.Height / 2));
                                BGElementList.Add(BGElement);
                                break;
                            case '8':
                                BGElement = new AnimatedTexture();
                                BGElement.Load(graphics.GraphicsDevice, content, levTex.BGElement8, levTex.BGElement8framesWide, levTex.BGElement8framesTall,
                                               levTex.BGElement8framesPerSec, 0, levTex.BGElement8lastFrame, levTex.BGElement8sym);
                                BGElement.SpritePosition = new Vector2((int)xPosition, 0 - (BGElement.aTexture.Height / 2));
                                BGElementList.Add(BGElement);
                                break;
                            case '9':
                                BGElement = new AnimatedTexture();
                                BGElement.Load(graphics.GraphicsDevice, content, levTex.BGElement9, levTex.BGElement9framesWide, levTex.BGElement9framesTall,
                                               levTex.BGElement9framesPerSec, 0, levTex.BGElement9lastFrame, levTex.BGElement9sym);
                                BGElement.SpritePosition = new Vector2((int)xPosition, 0 - (BGElement.aTexture.Height / 2));
                                BGElementList.Add(BGElement);
                                break;*/
                        //End of level:
                            //case '!': //end of level with boss fight, start boss battle and ending sequence
                            //    isBossDefeated = false;
                            //    endsequence = true;
                            //    break;
                            case '?': //end of level without boss, start ending sequence
                                isBossDefeated = false;
                                endsequence = true;
                                break;
                            default: break;

                        }
                    }
                    time = 0;
                    levelRowIndex++;
                }
            }
        }

        //Same as updateLayout() but for reading in the fireflies for the boss fight
        public void updateBossfliesLayout(List<List<char>> bossfliesMap, float elapsed, GraphicsDeviceManager graphics, ContentManager content, Viewport viewport)
        {
            bossfliesTime += elapsed;
            if (bossfliesRowIndex < bossfliesMap.Count)
            {
                if (bossfliesTime > 0.5f)
                {
                    for (bossfliesColumnIndex = 0; bossfliesColumnIndex < bossfliesMap[bossfliesRowIndex].Count; bossfliesColumnIndex++)
                    {
                        float xPosition = (bossfliesColumnIndex + 1) * 50;
                        char ch = bossfliesMap[bossfliesRowIndex][bossfliesColumnIndex];
                        Bug bugX;

                        if (ch == 'f')
                        {
                            bugX = new Bug(viewport.Height, "firefly", elapsed * 200, graphics, content);
                            bugX.Load(graphics.GraphicsDevice, content, "Images/Enemies/bug_firefly_bodystrip", 4, 1, 8, 0, 0, true);
                            bugX.SpritePosition = new Vector2((int)xPosition, 0 - (bugX.aTexture.Height / 2));
                            BossBugs1.Add(bugX);
                        }
                    }
                    bossfliesTime = 0;
                    bossfliesRowIndex++;
                }
            }
        }

        //function that keeps track of the growing and shrinking confidence meter
        public void updateConfidence(Bumblepig bumblepig)
        {
            //fConfidenceMeter = 200f;
            if (justPollenated)//if a flower was just pollenated, the meter grows
            {
                fStreakTimer = 0.0f;
                if (nStreakCount > nOldStreakCount && nStreakCount < 5) //if a streak is going, add to bonus multiplier
                {
                    //fStreakMultiplier += 0.25f;
                    fCurrentBoost = fCurrentBoost * fStreakMultiplier;
                    fTotalBoost += fCurrentBoost;
                }
                else 
                {                    
                    if (nOldStreakCount > 1) //if you've maxed out your streak, add the multiplier before dumping
                    { 
                        fCurrentBoost = fCurrentBoost * fStreakMultiplier;
                        fTotalBoost += fCurrentBoost;
                    }

                    //we don't really have score anymore, so this should go away
                    bumblepig.score += (int)(100 * nOldStreakCount * fStreakMultiplier);

                    //This stuff happens after each streak ends
                    fTotalConfidenceMeter += fTotalBoost;
                    fCurrentBoost = fBaseBoost;
                    fTotalBoost = fCurrentBoost;
                    
                }
                justPollenated = false;
                nOldStreakCount = nStreakCount;
            }

            //If you haven't pollenated a flower in a while, just dump the boost into the meter and start the streak over
            if (fStreakTimer > fStreakTimerLimit)
            {
                if (nStreakCount > 0)
                {
                    //This stuff happens after each streak ends    
                    fTotalConfidenceMeter += fTotalBoost;
                    fCurrentBoost = fBaseBoost;
                    fTotalBoost = fCurrentBoost;

                    //this stuff happens because the time ran out on the streak
                    fStreakTimer = 0.0f;
                    nStreakCount = 0;
                    nOldStreakCount = 0;
                }
                if (isFiveStreak) isFiveStreak = false;
            }

            if (nStreakCount == 5)
            {
                nStreakCount = 0;
                nOldStreakCount = 0;
                isFiveStreak = true;
            }

            //set the power up mode based on how full the meter is, and constantly drain it a little            
            if (fTotalConfidenceMeter < 0.0f)
            { fTotalConfidenceMeter = 0.0f; }
            if (fTotalConfidenceMeter < (ConfidenceFlowerFill.aTexture.Width * 0.25f))     // old second half of this equation: (ConfidenceMeter.aTexture.Height * 0.25f))
            { 
                nConfidenceMode = 0;
                fTotalConfidenceMeter -= fBaseDrain;
            }
            if (fTotalConfidenceMeter >= (ConfidenceFlowerFill.aTexture.Width * 0.25f) && fTotalConfidenceMeter < (ConfidenceFlowerFill.aTexture.Width * 0.5f)) //old equation: (ConfidenceMeter.aTexture.Height * 0.25f) && fTotalConfidenceMeter < (ConfidenceMeter.aTexture.Height * 0.5f))
            { 
                nConfidenceMode = 1;
                fTotalConfidenceMeter -= fDrain1;
            }
            if (fTotalConfidenceMeter >= (ConfidenceFlowerFill.aTexture.Width * 0.5f) && fTotalConfidenceMeter < (ConfidenceFlowerFill.aTexture.Width * 0.75f)) //old equation: (ConfidenceMeter.aTexture.Height * 0.5f) && fTotalConfidenceMeter < (ConfidenceMeter.aTexture.Height * 0.75f))
            { 
                nConfidenceMode = 2;
                fTotalConfidenceMeter -= fDrain2;
            }
            if (fTotalConfidenceMeter >= (ConfidenceFlowerFill.aTexture.Width * 0.75f)) //old equation: (ConfidenceMeter.aTexture.Height * 0.75f))
            { 
                nConfidenceMode = 3;
                fTotalConfidenceMeter -= fDrain3;
            }
            if (fTotalConfidenceMeter > ConfidenceFlowerFill.aTexture.Width) //old equation: ConfidenceMeter.aTexture.Height)
            { fTotalConfidenceMeter = ConfidenceFlowerFill.aTexture.Width; } //old equation: ConfidenceMeter.aTexture.Height; }

            ConfidenceFlowerFill.recWidth = fTotalConfidenceMeter; //old equation: ConfidenceMeter.recHeight = fTotalConfidenceMeter;
            //ConfidenceMeter.SpritePosition.Y += (fOldMeterPosition - fTotalConfidenceMeter); //old equation: ConfidenceMeter.SpritePosition.Y += (fOldMeterPosition - fTotalConfidenceMeter);
            fOldMeterPosition = fTotalConfidenceMeter;

            //nConfidenceMode = 3; //remove... for debugging power up mode 3 only

        }

        // scripted little sequence for the end of the level
        public void updateEndSequence(Bumblepig pig, Viewport viewport, float elapsed)
        {
            //if all the set up is complete, begin the last little animation
            if (pig.spritePosition.X == viewport.Width / 2 && pig.spritePosition.Y == viewport.Height / 1.5f
                && SidePig.SpritePosition.X < 0 - SidePig.aTexture.Width)
            { finalMoments = true; }

            if (finalMoments) //the last little animation
            {
                PicketFence.UpdateFrame(elapsed);
                //slide on the leafy 'end' and picket fence
                if (PicketFence.SpritePosition.Y < viewport.Height / 3)
                {
                    PicketFence.SpritePosition.Y += elapsed * 100;
                }
                else
                {
                    freezeBackround = true; //everything stops
                    //have bumblepig squeel with excitement and fly up off the screen
                    if (pig.BumbleBody.FrameRight == 1) //at a certain frame, move to the excited animation
                    {
                        //when start and stop animation logic is in, set the start and stop to different frames here
                    }
                    if (pig.BumbleBody.FrameRight == 4) //after the excited animation, freeze his body and fly off the screen
                    { pig.BumbleBody.Pause(); }
                    if (pig.BumbleBody.IsPaused && pig.spritePosition.Y >= 0 - pig.diveShadow - 50)
                    { pig.spritePosition.Y -= 8; }
                    if (pig.spritePosition.Y < 0 - pig.diveShadow - 50)
                    {
                        //start fading out   
                        //for now, just set end sequence to false and move on
                        endsequence = false;
                    }
                    //if (fade out is finished)
                    //{ endsequence = false; }
                }
            }
            else //setting up for the last little animation
            {
                //center the pig
                pig.spriteRotation = 0.0f;
                if (pig.spritePosition.X > viewport.Width / 2)
                { 
                    pig.spritePosition.X -= 4;
                    if (pig.spritePosition.X < viewport.Width / 2)
                    { pig.spritePosition.X = viewport.Width / 2; }
                }
                else if (pig.spritePosition.X < viewport.Width / 2)
                { 
                    pig.spritePosition.X += 4;
                    if (pig.spritePosition.X > viewport.Width / 2)
                    { pig.spritePosition.X = viewport.Width / 2; }
                }
                if (pig.spritePosition.Y > viewport.Height / 1.5)
                { 
                    pig.spritePosition.Y -= 4;
                    if (pig.spritePosition.Y < viewport.Height / 1.5)
                    { pig.spritePosition.Y = viewport.Height / 1.5f; }
                }
                else if (pig.spritePosition.Y < viewport.Height / 1.5)
                { 
                    pig.spritePosition.Y += 4;
                    if (pig.spritePosition.Y > viewport.Height / 1.5)
                    { pig.spritePosition.Y = viewport.Height / 1.5f; }                
                }
                
                //slide the HUD off the screen... we'll have to add sliding the text later
                if (SidePig.SpritePosition.X >= 0 - SidePig.aTexture.Width)
                {
                    SidePig.SpritePosition.X -= 2;
                    SidePigWings.SpritePosition.X -= 2;
                }
            }
        }

        //All the boss logic
        public void updateBossKid(Bumblepig bumblepig, float elapsed, SoundBank sfxBank)
        {
            
            Random BossRandomizer = new Random();
            FireCloud.SpritePosition.X = KidCan.SpritePosition.X;
            KidCan.UpdateFrame(elapsed);
            KidFace.UpdateFrame(elapsed);
            KidLighter.UpdateFrame(elapsed);

            KidFaceDetected.SpritePosition = KidFace.SpritePosition;
            KidFaceSniffling.SpritePosition = KidFace.SpritePosition;
            KidFaceSneezing.SpritePosition = KidFace.SpritePosition;
            

            if (initializingBoss)
            {
                freezeBackround = true;
                nSquirtIndex = 0;
                //move sprites into position
                KidCan.SpritePosition.Y += 200 * elapsed;
                KidFace.SpritePosition.Y += 200 * elapsed;
                KidLighter.SpritePosition.Y += 200 * elapsed;
                if (KidCan.SpritePosition.Y > KidCanAtRest.Y) KidCan.SpritePosition = KidCanAtRest;
                if (KidFace.SpritePosition.Y > KidFaceAtRest.Y) KidFace.SpritePosition = KidFaceAtRest;
                if (KidLighter.SpritePosition.Y > KidLighterAtRest.Y) KidLighter.SpritePosition = KidLighterAtRest;
                if (KidCan.SpritePosition == KidCanAtRest && KidFace.SpritePosition == KidFaceAtRest && KidLighter.SpritePosition == KidLighterAtRest)
                {
                    initializingBoss = false;
                    isMovingLighter = true;
                    isLighterAtRest = false;
                    nLighterDirection = 4; //1=N, 2=NE, 3=E, 4=SE, 5=S, 6=SW, 7=W, 8=NW
                }
                //geoff flies
                for (int i = 0; i < 3; i++)
                {
                    BossFlies[i].isVisible = true;
                }
                //end geoff flies
            }

            if (!isBossDying)
            {
                //geoff flies
                //update fly positions
                for (int i = 0; i < 3; i++)
                {
                    //draws the fly and its wings
                    BossFlies[i].UpdateBug(elapsed, FlyStartingPosition[i]);

                    /*if (BossFlies[i].dead)
                    {
                        BossFlies[i].dead = false;
                        BossFlies[i].SpritePosition = FlyStartingPosition[i];
                        BossFlies[i].isVisible = true;
                    }*/
                    if (BossFlies[i].isVisible && !BossFlies[i].dying)
                    {
                        FlyPath = Vector2.Subtract(KidLighter.SpritePosition, BossFlies[i].SpritePosition);
                        fFlyAngle = (float)Math.Atan2(FlyPath.Y, FlyPath.X);
                        BossFlies[i].SpritePosition.X += fBossFlyTopSpeed * (float)Math.Cos(fFlyAngle);
                        BossFlies[i].SpritePosition.Y += fBossFlyTopSpeed * (float)Math.Sin(fFlyAngle);

                    }
                }
                //end geoff flies

                // if 3 phases have passed, initiate breathing phase
                if (nPhaseCount >= 3)
                {
                    sneezingPhase = true;
                    isBreathingIn = true;
                    fBreathingTimer = 0.0f;
                    nPhaseCount = 0;
                }

                if (!isFireMoving && !sneezingPhase)
                {
                    if (Vector2.Distance(bumblepig.spritePosition, KidLighter.SpritePosition) < 250) //If bumblepig gets into the light, kid tries to fire spray him
                    {
                        isFireMoving = true;
                        isLighterAtRest = false;
                        isMovingLighter = false;
                    }
                }

                #region lighterMovement
                //move lighter around
                if (isMovingLighter && !sneezingPhase)
                {
                    
                    fLighterPatrolTimer += elapsed;
                    fLighterDirectionTimer += elapsed;

                    if (fLighterDirectionTimer > 0.5f)
                    {
                        fLighterDirectionTimer = 0.0f;
                        nLighterDirection = BossRandomizer.Next(1, 8);
                        //too high
                        if ((nLighterDirection == 1 || nLighterDirection == 2 || nLighterDirection == 8) && KidLighter.SpritePosition.Y < 250)
                        {
                            nLighterDirection = 5;
                        }
                        
                        //too low
                        if ((nLighterDirection == 4 || nLighterDirection == 5 || nLighterDirection == 6) && KidLighter.SpritePosition.Y > 600)
                        {
                            nLighterDirection = 1;
                        }
                        
                        //too left
                        if ((nLighterDirection == 6 || nLighterDirection == 7 || nLighterDirection == 8) && KidLighter.SpritePosition.X < 100)
                        {
                            nLighterDirection = 3;
                        }
                        
                        //too right
                        if ((nLighterDirection == 2 || nLighterDirection == 3 || nLighterDirection == 4) && KidLighter.SpritePosition.Y > 924)
                        {
                            nLighterDirection = 7;
                        }
                    }
                        
                    switch (nLighterDirection)
                        { 
                            case 1: //up
                                KidLighter.SpritePosition.Y -= fLighterTopSpeed;
                                break;

                            case 2: //up-right
                                KidLighter.SpritePosition.Y -= fLighterTopSpeed;
                                KidLighter.SpritePosition.X += fLighterTopSpeed;
                                break;

                            case 3: //right
                                KidLighter.SpritePosition.X += fLighterTopSpeed;
                                break;

                            case 4: //down-right
                                KidLighter.SpritePosition.Y += fLighterTopSpeed;
                                KidLighter.SpritePosition.X += fLighterTopSpeed;
                                break;

                            case 5: //down
                                KidLighter.SpritePosition.Y += fLighterTopSpeed;
                                break;

                            case 6: //down-left
                                KidLighter.SpritePosition.Y += fLighterTopSpeed;
                                KidLighter.SpritePosition.X -= fLighterTopSpeed;
                                break;

                            case 7: //left
                                KidLighter.SpritePosition.X -= fLighterTopSpeed;
                                break;

                            case 8: //up-left
                                KidLighter.SpritePosition.Y -= fLighterTopSpeed;
                                KidLighter.SpritePosition.X -= fLighterTopSpeed;
                                break;

                            default: //default
                                break;
                        
                        }
                    
                    if (fLighterPatrolTimer > 10.0f)
                    {
                        fLighterPatrolTimer = 0.0f;
                        isMovingLighter = false;
                    }

                }

                //move lighter back into position
                if (!isMovingLighter && !isLighterAtRest && !sneezingPhase)
                {
                    if (!isFireMoving) LighterReturnPath = Vector2.Subtract(KidLighterAtRest, KidLighter.SpritePosition); //back to upper left if he's not going to spray fire
                    else LighterReturnPath = Vector2.Subtract(LighterReturnPathToCan, KidLighter.SpritePosition); //up to spray can if he's going to spray fire

                    fLighterReturnAngle = (float)Math.Atan2(LighterReturnPath.Y, LighterReturnPath.X);

                    KidLighter.SpritePosition.X += fLighterTopSpeed * (float)Math.Cos(fLighterReturnAngle);
                    KidLighter.SpritePosition.Y += fLighterTopSpeed * (float)Math.Sin(fLighterReturnAngle);                

                    if (LighterReturnPath.Length() < 5.0f)
                    {
                        if (!isFireMoving)
                        {
                            KidLighter.SpritePosition = KidLighterAtRest;
                            nPhaseCount += 1;
                        }
                        else
                        {
                            KidLighter.SpritePosition.X = KidCan.SpritePosition.X;
                            KidLighter.SpritePosition.Y = KidCan.SpritePosition.Y + 100.0f;
                        }
                        isLighterAtRest = true;
                        nTotalSquirts = BossRandomizer.Next(1, 4);
                        nSquirtInterval = 1;                    
                    }
                }
                if (!isFireMoving && !isCanAtRest)
                {
                    KidCan.SpritePosition.X += 8;
                    if (KidCan.SpritePosition.X >= KidCanAtRest.X)
                    {
                        KidCan.SpritePosition = KidCanAtRest;
                        isCanAtRest = true;
                    }
                }
                if (isFireMoving && KidFace.SpritePosition.Y >= (0 - (KidFace.aTexture.Height / 2))) KidFace.SpritePosition.Y -= 4.0f;
                if (isCanAtRest && (KidFace.SpritePosition.Y < KidFaceAtRest.Y))
                {
                    KidFace.SpritePosition.Y += 8.0f;
                    if (KidFace.SpritePosition.Y > KidFaceAtRest.Y) KidFace.SpritePosition = KidFaceAtRest;
                }
            
                #endregion lighterMovement

                #region spraying
                //do spray can stuff
                if (isLighterAtRest && !isFireMoving && !sneezingPhase)
                {
                    fSquirtTimer += elapsed;
                    
                    
                    //interval is up, shoot next wave
                    if (fSquirtTimer > (float)nSquirtInterval && nSquirtIndex <= nTotalSquirts)
                    {                    
                        fSquirtTimer = 0.0f;
                        nSquirtIndex++;
                        //set time until next spray wave
                        nSquirtInterval = BossRandomizer.Next(1, 4);                    
                    }

                    

                    //spray phase is over
                    if (nSquirtIndex > nTotalSquirts && fSquirtTimer > 5.0f) //wait for last bullets to leave screen before moving the lighter again
                    {
                        for (int i = 0; i < (4 * nSquirtIndex); i++)
                        {
                            SprayClouds[i].SpritePosition = KidCanAtRest;
                        }
                        nSquirtIndex = 0;
                        fSquirtTimer = 0.0f;
                        isMovingLighter = true;
                        isLighterAtRest = false;
                        nLighterDirection = 4;
                        nPhaseCount += 1;
                    }
                }
                //keep track of active clouds, direction and hit detection
                //based on 4*nSquirtIndex, max of 16
                if (nSquirtIndex > 0)
                {
                    for (int i = 0; i < (4 * nSquirtIndex); i++)
                    {
                        //move clouds here
                        if (i == 0 || i == 8) //first cloud of wave 1 and 3
                        {
                            SprayClouds[i].SpritePosition.X -= 10;
                            SprayClouds[i].SpritePosition.Y += 2;
                        }
                        if (i == 1 || i == 9) //second cloud of wave 1 and 3
                        {
                            SprayClouds[i].SpritePosition.X -= 8;
                            SprayClouds[i].SpritePosition.Y += 4;
                        }
                        if (i == 2 || i == 10) //third cloud of wave 1 and 3
                        {
                            SprayClouds[i].SpritePosition.X -= 4;
                            SprayClouds[i].SpritePosition.Y += 8;
                        }
                        if (i == 3 || i == 11) //fourth cloud of wave 1 and 3
                        {
                            SprayClouds[i].SpritePosition.X -= 2;
                            SprayClouds[i].SpritePosition.Y += 10;
                        }
                        if (i == 4 || i == 12) //first cloud of wave 2 and 4
                        {
                            SprayClouds[i].SpritePosition.X -= 9;
                            SprayClouds[i].SpritePosition.Y += 3;
                        }
                        if (i == 5 || i == 13) //second cloud of wave 2 and 4
                        {
                            SprayClouds[i].SpritePosition.X -= 7;
                            SprayClouds[i].SpritePosition.Y += 5;
                        }
                        if (i == 6 || i == 14) //third cloud of wave 2 and 4
                        {
                            SprayClouds[i].SpritePosition.X -= 5;
                            SprayClouds[i].SpritePosition.Y += 7;
                        }
                        if (i == 7 || i == 15) //fourth cloud of wave 2 and 4
                        {
                            SprayClouds[i].SpritePosition.X -= 3;
                            SprayClouds[i].SpritePosition.Y += 9;
                        }
                    }
                }
                for (int i = 0; i < SprayClouds.Count; i++)
                {
                    SprayClouds[i].UpdateFrame(elapsed);
                    if (SprayClouds[i].SpritePosition.X < 0.0f - 100.0f || SprayClouds[i].SpritePosition.Y > 868.0f)
                    {
                        SprayClouds[i].SpritePosition = new Vector2(-100.0f, -100.0f);
                    }
                }
                #endregion spraying

                //do the flamethrower thing
                #region fireSpraying
                if (isFireMoving && isLighterAtRest)
                {
                    if (KidCan.SpritePosition == KidCanAtRest || (KidCan.SpritePosition.X < 750.0f && KidCan.SpritePosition.X > 743.0f) || (KidCan.SpritePosition.X < 500.0f && KidCan.SpritePosition.X > 493.0f) || (KidCan.SpritePosition.X < 250.0f && KidCan.SpritePosition.X > 243.0f)) isFireSpraying = true;

                    if (isFireSpraying)
                    {
                        fFireSprayTimer += elapsed;
                        FireCloud.SpritePosition.X = KidLighter.SpritePosition.X;
                        FireCloud.SpritePosition.Y = KidLighter.SpritePosition.Y + 200.0f;
                        FireCloud.UpdateFrame(elapsed);

                        //now lets try this growing thing
                        if (fFireSprayTimer < 0.5f)
                        {
                            FireCloud.recHeight = (fFireSprayTimer / 0.5f) * FireCloud.aTexture.Height;
                            //FireCloud.SpriteScale = (fFireSprayTimer / 0.5f);
                            fireBoxHeight = (fFireSprayTimer / 0.5f) * FireCloud.aTexture.Height;
                        }
                        else
                        {
                            FireCloud.recHeight = (1 - ((fFireSprayTimer - 0.5f) / 0.5f)) * FireCloud.aTexture.Height;
                            //FireCloud.SpriteScale = 1.0f - ((fFireSprayTimer - 0.5f) / 0.5f);
                            fireBoxHeight = (1 - ((fFireSprayTimer - 0.5f) / 0.5f)) * FireCloud.aTexture.Height;
                        }

                        if (fFireSprayTimer > 1.0f)
                        {
                            fFireSprayTimer = 0.0f;
                            isFireSpraying = false;
                        }
                        //hitbox for fire
                        fireBox = new HitBox2D(new Vector2((FireCloud.SpritePosition.X - (FireCloud.aTexture.Width / 2)), (FireCloud.SpritePosition.Y - (FireCloud.aTexture.Height / 2))),
                                           new Vector2((FireCloud.SpritePosition.X + (FireCloud.aTexture.Width / 2)), (FireCloud.SpritePosition.Y - (FireCloud.aTexture.Height / 2) + fireBoxHeight)));
                                           
                    }

                    if (!isFireSpraying)
                    {
                        isCanAtRest = false;
                        KidCan.SpritePosition.X -= 8.0f;
                        KidLighter.SpritePosition.X -= 8.0f;
                    }

                    if (KidCan.SpritePosition.X < 243.0f)
                    {
                        isFireMoving = false;
                        isLighterAtRest = false;
                    }
                }
                #endregion fireSpraying

                //Breathing in...
                #region Sneezing
                if (sneezingPhase)
                {

                    fBreathingTimer += elapsed;
                    if (isBreathingIn) //&& !isKidInvulnerable)
                    {
                        //need movenment stuff here too
                        if (fBreathingTimer > 1.5f)
                        {
                            isBreathingIn = false;
                            fBreathingTimer = 0.0f;
                            nPhaseCount += 1;
                        }
                        KidSniffles.UpdateFrame(elapsed);
                        Vector2 tempBumbleVector = new Vector2(KidFace.SpritePosition.X - bumblepig.spritePosition.X, KidFace.SpritePosition.Y - bumblepig.spritePosition.Y);
                        Vector2 tempBulletVector = new Vector2(KidFace.SpritePosition.X - bumblepig.Bullet.SpritePosition.X, KidFace.SpritePosition.Y - bumblepig.Bullet.SpritePosition.Y);

                        tempBumbleVector.Normalize();
                        tempBulletVector.Normalize();

                        tempBumbleVector = Vector2.Multiply(tempBumbleVector, fBreathingDistance);
                        tempBulletVector = Vector2.Multiply(tempBulletVector, fBreathingDistance);

                        bumblepig.spritePosition = Vector2.Add(bumblepig.spritePosition, tempBumbleVector);
                        bumblepig.Bullet.SpritePosition = Vector2.Add(bumblepig.Bullet.SpritePosition, tempBulletVector);

                        // need a FOR loop for all the bugs when fireflys get implemented into the boss fight
                    }

                    if (!isBreathingIn && fBreathingTimer > 0.5f)
                    {

                        isBreathingIn = true;
                        fBreathingTimer = 0.0f;
                        //reset the breathing lines frame
                        KidSniffles.FrameRight = 0;
                    }

                    //after breathing in 3 times, break out to the regular phases... hopefully where it left off
                    if (nPhaseCount >= 3)
                    {
                        nPhaseCount = 0;
                        fBreathingTimer = 0.0f;
                        sneezingPhase = false;
                    }

                }
                #endregion Sneezing

                //hit detection
                #region Boss hit detection

                for (int i = 0; i < 3; i++)
                {
                    BossFlies[i].CheckDamage(bumblepig, sfxBank, KidLighter.HitBox2);
                }

                if (KidFace.HitBox2.Intersects(bumblepig.BumbleBody.HitBox2) || KidCan.HitBox2.Intersects(bumblepig.BumbleBody.HitBox2) || KidLighter.HitBox2.Intersects(bumblepig.BumbleBody.HitBox2))
                {
                    bumblepig.HurtBumblepig(sfxBank);
                }
                if (isLighterAtRest && !isFireMoving && !sneezingPhase && nSquirtIndex > 0)
                {
                    for (int i = 0; i < SprayClouds.Count; i++)
                    {
                        if (SprayClouds[i].HitBox2.Intersects(bumblepig.BumbleBody.HitBox2)) bumblepig.HurtBumblepig(sfxBank);
                        for (int j = 0; j < 3; j++)
                        {
                            BossFlies[j].CheckDamage(SprayClouds[i].HitBox2);
                        }
                    }
                }
                if (isFireSpraying)
                {
                    if (fireBox.Intersects(bumblepig.BumbleBody.HitBox2)) bumblepig.HurtBumblepig(sfxBank);
                }
                if (isBreathingIn)
                {
                    if (!isKidInvulnerable && bumblepig.isExplosionVisible && bumblepig.ExplodedBullet.HitBox2.Contains(KidSniffles.SpritePosition))
                    {
                        nBossLife -= 1;
                        KidFaceSneezing.tint = Color.Red;
                        isKidInvulnerable = true;                    
                    }
                }
                if (isKidInvulnerable && !isBreathingIn)
                {
                    KidFaceSneezing.tint = Color.White;
                    isKidInvulnerable = false;
                    nPhaseCount = 0;
                    fBreathingTimer = 0.0f;
                    sneezingPhase = false;
                }
                if (nBossLife == 0) isBossDying = true;

                #endregion Boss hit detection
            }
            if(isBossDying)
            {
                //geoff flies
                for (int i = 0; i < 3; i++) BossFlies[i].dying = true;
                //end geoff flies

                //boss dying animations
                KidFace.tint = Color.White;
                KidFace.SpritePosition.Y -= 50.0f;
                KidLighter.SpritePosition.X -= 50.0f;
                KidCan.SpritePosition.X += 50.0f;
                isBreathingIn = false;

                if (KidFace.SpritePosition.Y < -500.0f && KidLighter.SpritePosition.X < -500.0f && KidCan.SpritePosition.X > 1500.0f) isBossDefeated = true;
                freezeBackround = false;
            }
            
            /*else
            {
                testTimer += elapsed;
                if (testTimer > 3.0f)
                {
                    isBossDefeated = true;
                    freezeBackround = false;
                }
            }*/
        }
    }
}